package com.vr.cloudpicture.manager;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.vr.cloudpicture.config.CosClientConfig;
import com.vr.cloudpicture.exception.ErrorCode;
import com.vr.cloudpicture.exception.ThrowUtils;
import com.vr.cloudpicture.model.dto.file.UploadPictureResult;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;



/**
 * 文件相关通用代码，在CosManager进一步封装，与业务有一点关系
 * @deprecated 已废弃，请使用upload包的模板方法优化
 * @author hzh
 * @date 2025/05/07
 */
@Deprecated
@Component
@RequiredArgsConstructor
@Slf4j
public class FileManager {
    private static final long ONE_M = 1024*1024L;
    private static final List<String> ALLOW_FORMAT_LIST = Arrays.asList("jpg","jpeg","png","gif","bmp","webp") ;

    private final CosManager cosManager;
    private final CosClientConfig cosClientConfig;
    /**
     * 上传图片
     *
     * @param multipartFile    Multipart 文件
     * @param uploadPathPrefix 上传路径前缀
     * @return {@code UploadPictureResult }
     */
    public UploadPictureResult uploadPicture(MultipartFile multipartFile,String uploadPathPrefix) {
        // 根据实际需求校验文件
        validPicture(multipartFile);
        // 生成图片上传地址
        String imagePath = generateUploadImagePath(multipartFile, uploadPathPrefix);
        File uploadFile = null;
        try {
            uploadFile = File.createTempFile(imagePath, null);
            multipartFile.transferTo(uploadFile);
            // 上传
            PutObjectResult putObjectResult = cosManager.putPictureObject(imagePath, uploadFile);
            return analyzerCosResult(AnalyzerCosParams.builder()
                    .imageName(FileUtil.mainName(multipartFile.getOriginalFilename()))
                    .imagePath(imagePath)
                    .picSize(multipartFile.getSize())
                    .putObjectResult(putObjectResult)
                    .build());
        } catch (IOException e) {
            log.error("file upload error {}", ExceptionUtil.getRootCauseMessage(e));
            ThrowUtils.throwIf(true, ErrorCode.SYSTEM_ERROR, "上传图片失败");
            throw new RuntimeException(e);
        } finally {
            // 删除临时文件
            deleteTempFile(uploadFile);
        }

    }

    private void deleteTempFile(File uploadFile) {
        if (uploadFile!=null) {
            boolean delete = uploadFile.delete();
            if (!delete) {
                log.error("file delete error,filepath={}", uploadFile.getAbsolutePath());
            }
        }
    }


    /**
     * 校验图片
     * @param multipartFile Multipart 文件
     */
    private void validPicture(MultipartFile multipartFile) {
        ThrowUtils.throwIf(multipartFile==null, ErrorCode.PARAMS_ERROR,"文件不能为空");
        // 1、校验文件大小
        long fileSize = multipartFile.getSize();
        ThrowUtils.throwIf(fileSize > 30*ONE_M, ErrorCode.PARAMS_ERROR, "文件大小不能超过30M");
        // 2、校验文件后缀
        String fileSuffix = FileUtil.getSuffix(multipartFile.getOriginalFilename());
        ThrowUtils.throwIf(!ALLOW_FORMAT_LIST.contains(fileSuffix), ErrorCode.PARAMS_ERROR, "文件类型错误");
    }


    /**
     * 生成上传图像路径
     *
     * @param multipartFile    Multipart 文件
     * @param uploadPathPrefix 上传路径前缀
     * @return {@code String }
     */
    private String generateUploadImagePath(MultipartFile multipartFile, String uploadPathPrefix) {
        String filename = multipartFile.getOriginalFilename();
        // 上传的文件名
        String uploadFilename=String.format("%s_%s.%s", LocalDate.now(), RandomUtil.randomString(16),filename);
        return String.format("%s/%s", uploadPathPrefix, uploadFilename);
    }

    private UploadPictureResult analyzerCosResult(AnalyzerCosParams params) {
        ImageInfo imageInfo = params.getPutObjectResult().getCiUploadResult().getOriginalInfo().getImageInfo();
        return UploadPictureResult.builder()
                .name(params.getImageName())
                .url(String.format("%s/%s", cosClientConfig.getHost(), params.getImagePath()))
                .picFormat(imageInfo.getFormat())
                .picHeight(imageInfo.getHeight())
                .picWidth(imageInfo.getWidth())
                .picSize(params.picSize)
                // 缩放比例
                .picScale(NumberUtil.round(imageInfo.getWidth()*1.0/imageInfo.getHeight(),2).doubleValue())
                .build();
    }
    /**
     * 不用成员变量而是封装起来，避免线程问题
     *
     * @author hzh
     * @date 2025/05/07
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    private static class AnalyzerCosParams {

        private PutObjectResult putObjectResult;
        private String imagePath;
        private String imageName;
        private Long picSize;
    }
}
